#ifndef SINGLETON_HPP
#define SINGLETON_HPP

#include <iostream>
#include <unistd.h>

// 线程不安全
class Singletion
{
  static Singletion *m_instance;

private:
  Singletion() {}
  // C++98
  // Singletion(const Sinletion&);
  // Singletion operator=(const Singletion&);
  // C++11
  Singletion(const Singletion &) = delete;
  Singletion &operator=(const Singletion &) = delete;

public:
  static Singletion *GetInstance()
  {
    // 这里会出现线程不安全
    if (m_instance == nullptr)
      m_instance = new Singletion();
    return m_instance;
  }
};
Singletion *Singletion::m_instance = nullptr;

// 使用单例模式实现抢票机制
class TicketGrab
{
private:
  static TicketGrab *m_instance;
  int _tickets = 10000;
  TicketGrab() {}
  TicketGrab(const TicketGrab &) = delete;
  TicketGrab &operator=(const TicketGrab &) = delete;

public:
  static TicketGrab *GetInstance()
  {
    if (m_instance == nullptr)
      m_instance = new TicketGrab();
    return m_instance;
  }

  void Grabbing(long fds)
  {
    if (_tickets > 0)
    {
      // 通过休眠可以使重入现象更加明显
      usleep(100);
      fprintf(stdout, "thread[%d]->tickets: %d\n", fds, --_tickets);
    }
  }

  int TicketNum()
  {
    return _tickets;
  }
};

#endif
